package com.recharge.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.recharge.common.util.Constant;
import com.recharge.core.entity.OrderEntity;
import com.recharge.core.entity.ProviderOrderEntity;
import com.recharge.core.mapper.OrderMapper;
import com.recharge.core.mapper.ProviderOrderMapper;
import com.recharge.domain.query.ProviderApiQueryDO;
import com.recharge.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.sql.Wrapper;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

@Service
public class TaskServiceImpl implements TaskService {

    @Autowired
    private OrderService orderService;

    @Autowired
    private RechargeService rechargeService;

    @Autowired
    private MerchantService merchantService;

    @Autowired
    private MerchantAccountService merchantAccountService;

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private ProviderApiService providerApiService;

    @Autowired
    private ProviderOrderMapper providerOrderMapper;

    private ExecutorService executorService = null;

    @Value("${node.name}")
    private Integer nodeName;


    /**
     * 系统初始化-> 创建线程池：
     *              1）线程池执行 OrderSubmitThread 线程（提交订单线程)
     *              2）线程池执行 SendCallBackTaskThread 线程（发送回调任务线程）；
     *              3）线程池执行 SysMerchantAccountTaskThread 线程（同步商户账户信息线程）；
     *              4）线程池执行 ProcessTimeThread 线程 （订单处理时长）；
     *              5）线程池执行 OrderSyncUpdate 线程 （订单同步修改线程）；
     *              6）线程池执行 SyncOrderStatus 线程 （订单同步状态）；
     *
     */
    @PostConstruct
    public void init() {
        executorService =  new ThreadPoolExecutor(10, 100,
                5,
                TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(512),
                new ThreadPoolExecutor.DiscardPolicy());
        start();
    }

    public void start() {

        executorService.execute(new SysMerchantAccountTaskThread());
        executorService.execute(new ProcessTimeThread());

    }

    /**
     * 下游商家账户信息线程->
     *        执行商家账户服务的 syncMerchantAccount（）方法
     */
    class SysMerchantAccountTaskThread implements Runnable {
        @Override
        public void run() {
            merchantAccountService.syncMerchantAccount();
        }
    }


    /**
     * 订单处理时长线程->
     *         1）根据订单节点，订单充值中（状态 5）或者订单未确认状态（7）查询出订单，执行修改订单的处理时长；
     *         2）根据订单节点，供货单状态（成功 3或者 未确认 4） 查询供货单，执行修改供货单处理时长；
     *
     */
    class ProcessTimeThread implements Runnable {

        public void run() {
            while(!Thread.currentThread().isInterrupted()) {
                QueryWrapper<OrderEntity> wrapper = new QueryWrapper<>();
                wrapper.and(w -> w.eq("node_name", nodeName).eq("status", Constant.RECHARGE_ORDER_STATUS_5)
                        .or()
                        .eq("status", Constant.RECHARGE_ORDER_STATUS_7));
                List<OrderEntity> list = null;
                try {
                    list = orderMapper.selectList(wrapper);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                for(OrderEntity entity : list) {
                    OrderEntity updateEntity = new OrderEntity();
                    updateEntity.setId(entity.getId());
                    updateEntity.setProcessTime(System.currentTimeMillis() - entity.getCreateDate().getTime());
                    try {
                        orderMapper.updateById(updateEntity);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }

                QueryWrapper<ProviderOrderEntity> wrapper1 = new QueryWrapper<>();
                wrapper1.and(w -> w.eq("node_name", nodeName).eq("status", Constant.PROVIDER_ORDER_STATUS_3)
                        .or()
                        .eq("status", Constant.PROVIDER_ORDER_STATUS_4));
                List<ProviderOrderEntity> list1 = null;
                try {
                    list1 = providerOrderMapper.selectList(wrapper1);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                for(ProviderOrderEntity entity : list1) {
                    ProviderOrderEntity updateEntity = new ProviderOrderEntity();
                    updateEntity.setId(entity.getId());
                    updateEntity.setProcessTime(System.currentTimeMillis() - entity.getProviderDate().getTime());
                    try {
                        providerOrderMapper.updateById(updateEntity);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }

                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
